package com.billdowney.util.regex;

import java.text.ParseException;
import java.util.Calendar;

import com.billdowney.util.DateUtil;

/**
 * 验证身份证
 * 
 * @author 超级小富翁 - BillDowney
 * @date 2019年3月29日 上午9:21:05
 */
public class IdCardUtil {

	// 校验码关系
	private static String[] checkNumberArray = { "1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2" };

	public static void main(String[] args) {
		String idCard = "500231199602250416";
		System.out.println(getInfo(idCard));
	}

	/**
	 * 验证身份证号，可验证18位身份证，15位身份证不需要验证
	 * 
	 * @param idCard 身份证号
	 * @return 是否符合规则
	 * @author: 超级小富翁 - BillDowney
	 * @date: 2019年3月29日 上午10:29:05
	 */
	public static boolean validation(String idCard) {
		switch (idCard.length()) {
		case 18:
			int nums = 0;
			for (int i = 0; i < idCard.length() - 1; i++) {
				String str = idCard.substring(i, i + 1);
				nums += calculateWeightedNum(18 - i) * Integer.valueOf(str);
			}
			if (checkNumberArray[nums % 11].equals(idCard.substring(17))) {
				return true;
			}
			break;
		case 15:
			return true;
		default:
			break;
		}
		return false;
	}

	/**
	 * 计算加权数
	 * 
	 * @param digit 位数
	 * @return 计算出的加权数
	 * @author: 超级小富翁 - BillDowney
	 * @date: 2019年3月29日 上午9:38:57
	 */
	public static int calculateWeightedNum(int digit) {
		return (int) (Math.pow(2, digit - 1) % 11);
	}

	/**
	 * 获取身份证相关信息，如果身份证不符合规则，则只返回isRight为false
	 * 
	 * @param idCard 身份证号
	 * @return 身份证相关信息
	 * @author: 超级小富翁 - BillDowney
	 * @date: 2019年3月29日 上午11:07:41
	 */
	public static IdCardInfo getInfo(String idCard) {
		IdCardInfo info = new IdCardInfo();
		info.setIdCard(idCard);
		if (validation(info.getIdCard())) {
			info.setRight(true);
			// 获取行政区划代码
			getAreaCode(info);
			// 获取出生日期
			getBornDate(info);
			// 获取顺序码
			getOrderCode(info);
			// 获取性别
			getSex(info);
			// 获取校验码
			getCheckCode(info);
		} else {
			info.setRight(false);
		}
		return info;
	}

	/**
	 * 获取行政区划代码
	 * 
	 * @param info 身份证信息
	 * @return
	 * @author: 超级小富翁 - BillDowney
	 * @date: 2019年3月29日 上午11:13:26
	 */
	public static IdCardInfo getAreaCode(IdCardInfo info) {
		info.setAreaCode(info.getIdCard().substring(0, 6));
		return info;
	}

	/**
	 * 获取出生日期
	 * 
	 * @param info 身份证信息
	 * @return
	 * @author: 超级小富翁 - BillDowney
	 * @date: 2019年3月29日 上午11:20:23
	 */
	public static IdCardInfo getBornDate(IdCardInfo info) {
		String dateStr = info.getIdCard().substring(6, 14);
		try {
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(DateUtil.getDateByFormat(dateStr, "yyyyMMdd"));
			info.setBornDate(DateUtil.getDateShortStr(calendar.getTime()));
			info.setBornYear(calendar.get(Calendar.YEAR));
			info.setBornMonth(calendar.get(Calendar.MONTH) + 1);
			info.setBornDay(calendar.get(Calendar.DATE));
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return info;
	}

	/**
	 * 获取顺序码
	 * 
	 * @param info 身份证信息
	 * @return
	 * @author: 超级小富翁 - BillDowney
	 * @date: 2019年3月29日 下午1:51:33
	 */
	public static IdCardInfo getOrderCode(IdCardInfo info) {
		info.setOrderCode(info.getIdCard().substring(14, 17));
		return info;
	}

	/**
	 * 获取性别
	 * 
	 * @param info 身份证信息
	 * @return
	 * @author: 超级小富翁 - BillDowney
	 * @date: 2019年3月29日 下午1:53:51
	 */
	public static IdCardInfo getSex(IdCardInfo info) {
		int num = Integer.parseInt(info.getIdCard().substring(16, 17));
		switch (num % 2) {
		case 0:
			info.setSex(SexEnum.WOMAN);
			break;
		case 1:
			info.setSex(SexEnum.MAN);
			break;
		default:
			break;
		}
		return info;
	}

	/**
	 * 获取校验码
	 * 
	 * @param info 身份证信息
	 * @return
	 * @author: 超级小富翁 - BillDowney
	 * @date: 2019年3月29日 下午1:56:27
	 */
	public static IdCardInfo getCheckCode(IdCardInfo info) {
		info.setCheckCode(info.getIdCard().substring(17, 18));
		return info;
	}

}
